package com.corpgovernment.organization.service.impl;

import com.corpgovernment.api.applytrip.soa.request.ApplyTripPersonEffectRequest;
import com.corpgovernment.api.applytrip.soa.response.TripPersonEffectResponse;
import com.corpgovernment.api.costcenter.model.CostCenter;
import com.corpgovernment.api.organization.model.passenger.PassengerVo;
import com.corpgovernment.common.base.BaseRequestVO.UserInfo;
import com.corpgovernment.costcenter.entity.db.MbOrgProjectInfo;
import com.corpgovernment.costcenter.service.IProjectInfoService;
import com.corpgovernment.costcenter.service.impl.CostCenterServiceImpl;
import com.corpgovernment.organization.dataloader.ApplyTripClientLoader;
import com.corpgovernment.organization.vo.GetPassengerRequestVO;
import com.corpgovernment.organization.vo.GetPassengerResponseVO;
import com.corpgovernment.organization.vo.PassengerInfoVO;
import com.ctrip.corp.obt.generic.utils.CollectionUtils;
import com.ctrip.corp.obt.generic.utils.JsonUtils;
import com.ctrip.corp.obt.generic.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author jhxue
 * @create 2022-02-25-14:33
 */
@Service
@Slf4j
public class PassengerTravelService extends AbstractPassengerService {

	@Autowired
	private ApplyTripClientLoader applyTripClientLoader;

	@Autowired
	private CostCenterServiceImpl costCenterServiceImpl;

	@Autowired
	private IProjectInfoService projectInfoService;

	/**
	 * 查询出行人
	 *
	 * @param request
	 * @return
	 */
	@Override
	public GetPassengerResponseVO getPassenger(GetPassengerRequestVO request) {
		try {
			initElkLog();
			addElkInfoLog("校验出行人流程");
			UserInfo userInfo = request.getUserInfo();
			// 1.查询出行人信息
			addElkInfoLog("出差申请单模式");
			// 根据出差申请单获取出行人
			List<PassengerVo> passengerList = this.getPassengerByTravel(request);
			log.info("#getPassenger申请单获取到的出行人：{}",passengerList);
			// 2.完善出行人信息
			passengerList = this.packagePassengerList(passengerList, request);
			// 3.出行人排序
			passengerList = this.sort(passengerList, userInfo);
			//分页
			passengerList = toPage(passengerList, request);
			// 4.封装返回
			return GetPassengerResponseVO.create(passengerList, false);
		} finally {
			log.info("PassengerService.getPassenger获取可用出行人{} request：{}{}{}{}", System.lineSeparator(), JsonUtils.toJsonString(request), System.lineSeparator(), System.lineSeparator(), this.getElkInfoLog());
			clearElkLog();
		}
	}

	/**
	 * 对出差申请单出行人进行分页
	 * @param passengerList
	 * @param request
	 * @return
	 */
	private List<PassengerVo> toPage(List<PassengerVo> passengerList, GetPassengerRequestVO request) {
		if (CollectionUtils.isEmpty(passengerList)) {
			return new ArrayList<>();
		}
		Integer page = request.getPage();
		Integer pageSize = 10;
		int passengerLength = passengerList.size();
		int total  = (page * pageSize) > passengerLength ? passengerLength : (page * pageSize);
		int startNum = (page - 1) * pageSize;
		if (startNum > passengerLength) {
			return new ArrayList<>();
		}
		return passengerList.subList(startNum, total);
	}

	/**
	 * 根据出差申请单获取出行人
	 *
	 * @param requestVO
	 * @return
	 */
	private List<PassengerVo> getPassengerByTravel(GetPassengerRequestVO requestVO) {
		// 1.调用出差申请的soa接口可用的出行人
		UserInfo userInfo = requestVO.getUserInfo();
		String site = requestVO.getSite();
		Integer returnType = requestVO.getReturnType();
		ApplyTripPersonEffectRequest request = new ApplyTripPersonEffectRequest();
		request.setApplyNo(requestVO.getTravelId());
		request.setTrafficId(requestVO.getTripId());
		request.setStartCityCode(requestVO.getDcity());
		request.setEndCityCode(requestVO.getAcity());
		request.setReturnType(returnType);
		request.setUid(userInfo.getUid());
		request.setOrgId(userInfo.getOrgId());
		request.setStartDate(requestVO.getStartDate());
		request.setEndDate(requestVO.getEndDate());
		request.setReturnType(requestVO.getReturnType());
		request.setStartCityName(requestVO.getDepartCityName());
		request.setEndCityName(requestVO.getArrivalCityName());
		request.setTrafficType(site);
		request.setUseCarType(requestVO.getUseCarType());
		request.setCarCityCode(requestVO.getCarCityCode());
		request.setCarCityName(request.getEndCityName());
		List<TripPersonEffectResponse> personList = applyTripClientLoader.listEffectTripPerson(request);
		log.info("#applyTripClientLoader.listEffectTripPerson查询的数据为:{}",personList);
		if (CollectionUtils.isEmpty(personList)) {
			return Collections.emptyList();
		}
		// 2.获取出差申请单中的出行人
		List<PassengerVo> passengerList = setCostCenterAndProjectId(passengerConvert.convertFromTripPerson(personList));
		if (StringUtils.isNotBlank(requestVO.getQuery())){
			passengerList = passengerList.stream().filter(item -> StringUtils.isNotBlank(item.getName()) && item.getName().indexOf(requestVO.getQuery()) > -1).collect(Collectors.toList());
		}
		List<PassengerInfoVO> selectedList = requestVO.getSelectedList();
		log.info("#passengerConvert.convertFromTripPerson转换的数据为:{},#selectedList数据：{}",passengerList,selectedList);
		if (CollectionUtils.isEmpty(selectedList)) {
			return passengerList;
		}
		// 将选中的员工排掉
		List<String> uidList = selectedList.stream().filter(p -> StringUtils.isNotBlank(p.getUid())).map(PassengerInfoVO::getUid).collect(Collectors.toList());
		List<String> noUidList = selectedList.stream().filter(p -> StringUtils.isNotBlank(p.getNoEmployeeId())).map(PassengerInfoVO::getNoEmployeeId).collect(Collectors.toList());
		return passengerList.stream().filter(e -> !uidList.contains(e.getUid()) && !noUidList.contains(e.getNoEmployeeId())).collect(Collectors.toList());

	}


	private List<PassengerVo> setCostCenterAndProjectId(List<PassengerVo> list){
		log.info("setCostCenterAndProjectId 入参：{}",JsonUtils.toJsonString(list));
		/**
		 * 1.求出没有ID的成本中心和项目号
 		 */
		Set<String> costCenterCodeMap = new HashSet<>();
		Set<String> projectCodeMap = new HashSet<>();
		if (CollectionUtils.isNotEmpty(list)) {
			for(PassengerVo passenger:list){
				CostCenter costCenter = passenger.getCostCenter();
				PassengerVo.ProjectInfo project = passenger.getProjectInfo();
				if((costCenter!=null && costCenter.getId()==null)
						||(StringUtils.isNotBlank(passenger.getCostCenterCode()) && passenger.getCostCenterId()==null)){
					costCenterCodeMap.add(costCenter.getCostCenterCode());
				}
				if(StringUtils.isNotBlank(passenger.getProjectCode()) && passenger.getProjectId()==null){
					projectCodeMap.add(passenger.getProjectCode());
				}
			}
		}
		/**
		 * 2.反查成本中心和项目号
		 */
		Map<String, CostCenter> costCenterMap = new HashMap<>();
		Map<String, MbOrgProjectInfo> projectMap = new HashMap<>();
		if(CollectionUtils.isNotEmpty(costCenterCodeMap)){
			List<CostCenter> costCenterList = costCenterServiceImpl.listCostCenterByCode(costCenterCodeMap);
			if(CollectionUtils.isNotEmpty(costCenterList)){
				costCenterMap = costCenterList.stream().collect(Collectors.toMap(p->(p.getCostCenterCode()+"_"+p.getCompanyId()), Function.identity(), (k1,k2)->k1));
			}
		}

		if(CollectionUtils.isNotEmpty(projectCodeMap)){
			List<MbOrgProjectInfo> projectList = projectInfoService.listByProjectCode(projectCodeMap);
			projectMap = projectList.stream().collect(Collectors.toMap(p->(p.getProjectCode()+"_"+p.getCompanyId()), Function.identity(), (k1,k2)->k1));
		}

		/**
		 * 3.回填成本中心id和项目号id
		 */
		for(PassengerVo passenger:list){
			CostCenter costCenter = passenger.getCostCenter();
			PassengerVo.ProjectInfo project = passenger.getProjectInfo();
			if(costCenter!=null && costCenter.getId()==null){
				CostCenter cc = costCenterMap.get(costCenter.getCostCenterCode()+"_"+passenger.getCorpId());
				if(cc==null){
					cc = costCenterMap.get(costCenter.getCostCenterCode()+"_"+passenger.getOrgId());
				}
				if(cc != null){
					costCenter.setId(cc.getId());
					passenger.setCostCenterId(cc.getId().toString());
				}
			}
			if(project!=null && project.getProjectId()==null){
				MbOrgProjectInfo p = projectMap.get(project.getProjectCode()+"_"+passenger.getCorpId());
				if(p==null) {
					p = projectMap.get(project.getProjectCode() + "_" + passenger.getOrgId());
				}
				if(p!=null){
					project.setProjectId(p.getId().toString());
					passenger.setProjectId(p.getId().toString());
				}
			}
		}
		log.info("setCostCenterAndProjectId 出参：{}",JsonUtils.toJsonString(list));
		return list;
	}

	@Override
	public String getType() {
		return "TRAVEL";
	}
}
